#include "LoRA.h"

#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <linux/spi/spidev.h>
#include <linux/types.h>
#include <sys/ioctl.h>
#include <linux/ioctl.h>


PacketParams_t PacketParams;
PacketStatus_t PacketStatus;

ModulationParams_t modulationParams;

#define RF_FREQUENCY  434000000 // Hz

#define TX_OUTPUT_POWER   22 //The range of the output power is [-18..+13] dBm

#define TX_TIMEOUT_VALUE                            0xFFFF // ms
//#define RX_TIMEOUT_VALUE                            12800 // 200ms
#define RX_TIMEOUT_VALUE                            6400 // 100ms

const uint16_t RxIrqMask = IRQ_RX_DONE | IRQ_CRC_ERROR | IRQ_RX_TX_TIMEOUT;
const uint16_t TxIrqMask = IRQ_TX_DONE | IRQ_RX_TX_TIMEOUT;

int  spi_sx = -1;


bool LoRA_Open(IRQ_CALLBACK irq)
{
        uint32_t    max_speed_hz = 10000000;
    uint8_t     mode;

	Reset();

	// 初始化SPI口
	spi_sx = open("/dev/spidev1.0", O_RDWR, 0);

    if (spi_sx == -1)
    {
        return false;
    }

    // Set mode
    if (ioctl(spi_sx, SPI_IOC_RD_MODE, &mode) == -1)
    {
        close(spi_sx);
        spi_sx = -1;
        return false;
    }

    mode = (0x0 & ~(SPI_CPHA | SPI_CPOL)) | mode;

    if (ioctl(spi_sx, SPI_IOC_WR_MODE, &mode) == -1)
    {
        close(spi_sx);
        spi_sx = -1;
        return false;
    }

    // Set max speed
    if (ioctl(spi_sx, SPI_IOC_WR_MAX_SPEED_HZ, &max_speed_hz) == -1)
    {
        close(spi_sx);
        spi_sx = -1;
        return false;
	}

    // 初始化LoRA模组
    modulationParams.PacketType = PACKET_TYPE_LORA;
	modulationParams.Params.LoRa.SpreadingFactor = LORA_SF9;
	modulationParams.Params.LoRa.Bandwidth = LORA_BW_500;
	modulationParams.Params.LoRa.CodingRate = LORA_CR_4_7;

	PacketParams.PacketType = PACKET_TYPE_LORA;
	PacketParams.Params.LoRa.PreambleLength = 0x08;
	PacketParams.Params.LoRa.HeaderType = LORA_PACKET_VARIABLE_LENGTH;
	PacketParams.Params.LoRa.PayloadLength = 0;
	PacketParams.Params.LoRa.CrcMode = LORA_CRC_ON;
	PacketParams.Params.LoRa.InvertIQ = LORA_IQ_NORMAL;

	sx1262_Init();
	sx1262_SetRegulatorMode(USE_DCDC);

	sx1262_SetStandby(STDBY_XOSC);
	sx1262_SetPacketType(modulationParams.PacketType);
	sx1262_SetModulationParams(&modulationParams);
	sx1262_SetPacketParams(&PacketParams);

	sx1262_SetRfFrequency( RF_FREQUENCY);
	sx1262_SetBufferBaseAddresses(0x00, 0x00);
	sx1262_SetTxParams( TX_OUTPUT_POWER, RADIO_RAMP_20_US);

	sx1262_SetDioIrqParams(RxIrqMask | TxIrqMask, RxIrqMask | TxIrqMask, IRQ_RADIO_NONE, IRQ_RADIO_NONE);

	sx1262_SetLoRaSymbNumTimeout(0);

    sx126x_IRQ(irq);

    return true;
}

void LoRA_Close()
{
    close(spi_sx);
    spi_sx = -1;
}


// 发送数据
bool LoRA_Write(const uint8_t* data, uint8_t datasize)
{
    // 写入数据（会在函数内自动进入TX模式）
    PacketParams.Params.LoRa.PayloadLength = datasize;
	sx1262_SetPacketParams(&PacketParams);
	sx1262_SendPayload((uint8_t*)data, datasize, 0xFFFF);

    // 等待发送结束（暂定在外部等待）

}

// 读取数据，并获得当次数据接收时的RSSI等数据
bool LoRA_Read(uint8_t* data, uint8_t* datasize)
{
    uint8_t     tempBuf[255];       // Max Lora Packet Size
    uint8_t	    size = 0;

    sx1262_GetPayload(tempBuf, &size, (uint8_t)sizeof(tempBuf));

    if (size > *datasize)
    {
        *datasize = size;
        return false;
    }
    else
    {
        memcpy(data, tempBuf, size);
        *datasize = size;

        return true;
    }
}

// 读取RSSI和SNR
void LoRA_GetPacketStatus(int8_t* rssi, int8_t* snr)
{
    PacketStatus_t packetStatus;
	sx1262_GetPacketStatus(&packetStatus);
	*rssi = packetStatus.Params.LoRa.RssiPkt;
	*snr = packetStatus.Params.LoRa.SnrPkt;
}

void LoRA_StartReceive()
{
    sx1262_SetRxBoosted( 0 );
}

void LoRA_EndReceive()
{
    sx1262_SetStandby(STDBY_XOSC);
}

uint16_t LoRA_GetIRQ()
{
    return sx1262_ProcessIrqs();
}


